package com.ysw.rpc.server.config;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.fastjson2.JSON;
import com.ysw.rpc.common.constants.RpcConstants;
import com.ysw.rpc.server.annotatiaon.RpcService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 元数据注册
 *
 * @author YinShangwen
 * @since 2023/4/10 15:36
 */
public class NacosDiscoveryPropertiesBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {
    private ApplicationContext applicationContext;
    private final ServerProperties properties;

    public NacosDiscoveryPropertiesBeanPostProcessor(ServerProperties properties) {
        this.properties = properties;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof NacosDiscoveryProperties) {
            Set<String> classes = new HashSet<>();
            for (Object value : applicationContext.getBeansWithAnnotation(RpcService.class).values()) {
                Class<?> clazz = value.getClass();
                if (clazz.isInterface()) {
                    classes.add(clazz.getName());
                } else {
                    classes.add(clazz.getInterfaces()[0].getName());
                }
            }
            Map<String, String> metadata = ((NacosDiscoveryProperties) bean).getMetadata();
            Map<String, Object> rpcMetadata = new HashMap<>(16);
            rpcMetadata.put(RpcConstants.METADATA_PORT_KEY, properties.getPort());
            rpcMetadata.put(RpcConstants.METADATA_API_KEY, classes);
            metadata.put(RpcConstants.METADATA_KEY, JSON.toJSONString(rpcMetadata));
        }
        return bean;
    }
}
